package com.basic.library.binding.viewadapter.edittext;


import android.annotation.SuppressLint;
import android.content.Context;
import android.text.InputFilter;
import android.text.Layout;
import android.text.StaticLayout;
import android.text.TextPaint;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.TextView;

import androidx.databinding.BindingAdapter;

import com.basic.library.R;
import com.basic.library.base.ConstConfig;
import com.basic.library.binding.command.BindingCommand;
import com.basic.library.utils.EditInputFilter;
import com.jakewharton.rxbinding3.widget.RxTextView;
import com.jakewharton.rxbinding3.widget.TextViewTextChangeEvent;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import io.reactivex.android.schedulers.AndroidSchedulers;

/**
 * Created by goldze on 2017/6/16.
 */

public class ViewAdapter {
    /**
     * EditText重新获取焦点的事件绑定
     */
    @BindingAdapter(value = {"requestFocus1"}, requireAll = false)
    public static void requestFocusCommand(EditText editText, final Boolean needRequestFocus) {
        if (needRequestFocus) {
            editText.setSelection(editText.getText().length());
            editText.requestFocus();
            InputMethodManager imm = (InputMethodManager) editText.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
            imm.showSoftInput(editText, InputMethodManager.SHOW_IMPLICIT);
        }
        editText.setFocusableInTouchMode(needRequestFocus);
    }

    /**
     * EditText输入文字改变的监听
     * （见鬼， 绑定的时候，直接回调了一次 ，需注意某些接口调用时机就有变化）
     */
    @SuppressLint("CheckResult")
    @BindingAdapter(value = {"textChanged", "changedTimeout"}, requireAll = false)
    public static void addTextChangedListener(TextView editText,
                                              final BindingCommand<String> textChanged,
                                              long changedTimeout) {
//        editText.addTextChangedListener(new TextWatcher() {
//            @Override
//            public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
//
//            }
//
//            @Override
//            public void onTextChanged(CharSequence text, int i, int i1, int i2) {
//                if (textChanged != null) {
//                    textChanged.execute(text.toString());
//                }
//            }
//
//            @Override
//            public void afterTextChanged(Editable editable) {
//
//            }
//        });
        if (textChanged == null) return;
        if (changedTimeout == 0)
            changedTimeout = 350;
        //缺个生命周期绑定
        if (textChanged.disposable != null)
            textChanged.disposable.call(RxTextView.textChanges(editText)
                    .debounce(changedTimeout, TimeUnit.MILLISECONDS)
                    .observeOn(AndroidSchedulers.mainThread())
                    //CharSequence转换为String
                    .map(CharSequence::toString)
                    .subscribe(textChanged::execute));
        else
            RxTextView.textChanges(editText)
                    .debounce(changedTimeout, TimeUnit.MILLISECONDS)
                    .observeOn(AndroidSchedulers.mainThread())
                    //CharSequence转换为String
                    .map(CharSequence::toString)
                    .subscribe(textChanged::execute);
    }

    /**
     * EditText输入文字改变的监听(直接传入完整监听函数)
     */
    @SuppressLint("CheckResult")
    @BindingAdapter(value = {"textChangeEvent", "changedTimeout"}, requireAll = false)
    public static void addTextChangeEventListener(TextView editText,
                                                  final BindingCommand<TextViewTextChangeEvent> textChangeEvent,
                                                  long changedTimeout) {
        if (textChangeEvent == null) return;
        if (changedTimeout == 0)
            changedTimeout = 350;
        if (textChangeEvent.disposable != null)
            textChangeEvent.disposable.call(RxTextView.textChangeEvents(editText)
                    .debounce(changedTimeout, TimeUnit.MILLISECONDS)
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(textChangeEvent::execute));
        else
            RxTextView.textChangeEvents(editText)
                    .debounce(changedTimeout, TimeUnit.MILLISECONDS)
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(textChangeEvent::execute);
    }

    /**
     * xml使用需要加上@{}，否则无法覆盖
     * (弊端 ：行数限制满了，字数限制没满) 和setMyMaxLength相比，这个比较灵活 ，maxLines可以随便设
     *
     * @param editText
     * @param max
     */
    @BindingAdapter(value = {"android:maxLines"}, requireAll = false)
    public static void setMyMaxLines(EditText editText, final int max) {
        ConstConfig.INSTANCE.setMyMaxLines(editText, max);
    }

    /**
     * 根据字数，来限制行数(弊端 ：需求要分段,行数限制满了，字数限制没满 所以加了autoLimitLines)
     *
     * @param editText
     * @param max
     * @param autoLimitLines
     */
    @BindingAdapter(value = {"android:maxLength", "autoLimitLines"}, requireAll = false)
    public static void setMyMaxLength(EditText editText, final int max, final boolean autoLimitLines) {
        editText.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
            @Override
            public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
                editText.removeOnLayoutChangeListener(this);
                editText.setFilters(new InputFilter[]{new InputFilter.LengthFilter(max)});
                if (autoLimitLines) {
                    int size = getLineMaxNumber("我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我我",
                            editText.getPaint(), editText.getWidth());
                    ConstConfig.INSTANCE.setMyMaxLines(editText, max / (size - 1) + 1);
                }
            }
        });
    }

    public static Map<Object, EditInputFilter> map = new HashMap<>();

    @BindingAdapter(value = {"moneyLimit"}, requireAll = false)
    public static void setValueLimit(EditText editText, String max) {
        if (max == null)
            max = "0.0";
        Object key = editText.getTag(R.id.tagEditInputFilter);
        if (key != null) {
            EditInputFilter filter = map.get(key);
            if (filter != null)
                filter.setMAX_VALUE(max);
        } else {
            String random = System.currentTimeMillis() * Math.random() + "";
            map.put(random, new EditInputFilter(editText, max, random));
        }
    }

    static int getLineMaxNumber(String text, TextPaint paint, int maxWidth) {
        if (null == text || "".equals(text)) {
            return 0;
        }
        StaticLayout staticLayout = new StaticLayout(text, paint, maxWidth, Layout.Alignment.ALIGN_NORMAL
                , 1.0f, 0, false);
        //获取第一行最后显示的字符下标
        return staticLayout.getLineEnd(0);
    }
}
